#ifndef _LINKTREE_H_
#define _LINKTREE_H_

#include "DoubleLinkList.h"
#include <string>

class LinkTree;//前置声明
class TreeNode//树的节点
{
public:
    using ElementType = void*;

    

    TreeNode(const ElementType &element);
    //将一个节点绑定成另一个节点的孩子
    void Connect(TreeNode *parent);
    //解绑
    void Disconnect(TreeNode*parent);

    TreeNode *GetParent(){return parent;}

    ElementType GetData(){return data;}

    void SetData(const ElementType& element){data = element;}

    friend LinkTree;
private:
    ElementType data;//数据域
    TreeNode *parent;//双亲节点  前驱
    TreeNode *firstChild;//第一个孩子指针  后驱
    TreeNode * nextSbling;//下一个兄弟指针
};

class LinkTree
{
public:
    using ElementType = TreeNode::ElementType;
    void SetPrint( void (*Print)(void *))
    {
        this->Print = Print;
    }
    void SetCompare (bool (*Compare)(void * ,void *))
    {
        this->Compare = Compare;
    }
    void SetFree(void (*Free)(void *))
    {
        this->Free = Free;
    }
    void SetCopy(ElementType (*Copy)(ElementType))
    {
        this->Copy = Copy;
    }

    LinkTree();
    ~LinkTree();

    TreeNode * GetRoot(){return root;}

    DoubleLinkList FindByElement(const ElementType &element);

    int GetTreeHeight();

    //统计树中节点数量
    int Size();

    //统计树种叶子节点数量
    int LeafSize();
    
    void show();
private:
    void GetNodeLeafSize(TreeNode *node,int &count);
    void GetNodeSize(TreeNode *node,int &count);
    int GetNodeHeight(TreeNode *node);
    void FindNode(TreeNode *node,const ElementType &element,DoubleLinkList&list);
    void show(TreeNode *node,int deepth);
    void FreeNode(TreeNode *node);
    TreeNode *root;//根节点

    void (*Print)(void *);
    bool (*Compare)(ElementType element1 ,ElementType element2);
    void (*Free)(void *);
    ElementType (*Copy)(ElementType);

};

#endif